home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / lucifer.cq / lucifer.c
Text File  |  1985-02-08  |  18KB  |  472 lines

  1. /*"void~" will have to be #define'd int*/
  2.  
  3. /***************************** lucifer **************************
  4.  * LUCIFER: encrypt/decrypt bytes using IBM's LUCIFER algorithm.
  5.  * Programmed by R.W.Outerbridge
  6.  *
  7.  * Usage: lucifer (+|-)([ecb]|<cbc|cks>) key1 <ivec>
  8.  *                EN/DE    MODES         KEYS
  9.  *
  10.  *      + :     ENcrypt (default if MODE specified)
  11.  *      - :     DEcrypt (presumes encrypted input)
  12.  *
  13.  *      Modes of Operation (choose ONE):
  14.  *
  15.  *      ecb : (default) Electronic Code Book.  Only uses one key.
  16.  *              If simply "+" or "-" is specified, ecb is used.
  17.  *      cbc : Cipher Block Chaining.  Uses two keys.
  18.  *      cks : ChecKSum.  Generates a 128-bit checksum using two keys.
  19.  *
  20.  *      Both keys may be as long as you wish.  The practical limit
  21.  *      on keylength is the size of your system's argument buffer.
  22.  *      WARNING: on some machines all arguments become CAPITALS.
  23.  *      WARNING: non-ascii machines MAY get different results.
  24.  *
  25.  *      Any character may be used in keys - depending on the O/S -
  26.  *      except ASCII NULL (0x00).  The one-letter key '#', when used 
  27.  *      for "key1", will cause lucifer to use a preset default key
  28.  *      (for verification and testing).  Failing to specify "ivec", if
  29.  *      required, will result in "key1" being used for both keys.  It
  30.  *      is an error to omit "key1".  There is no provision for giving
  31.  *      arbitrary, absolute, bit-valued keys.
  32.  *
  33.  *      As painful as they are to use, long keys are MUCH safer;
  34.  *      think up nonsense phrases you can safely remember.
  35.  *
  36.  */
  37.  
  38. #include <stdio.h>
  39. #define toascii(a)      ((a)&0177)
  40. #define EN      0
  41. #define DE      1
  42. #define CKS     2
  43. #define MODS    3
  44. typedef char    BYTE;   /* BYTE = (VAX) ? int : char;   */
  45.         
  46. /* cryptographic declarations   */
  47. void copy16(), xor16(), getkey(), loadkey(), lucifer();
  48. BYTE Block[16], Link[16], Temp[16], IV[16];
  49. BYTE DFLTKY[16] = { 1,35,69,103,137,171,205,239,254,220,186,152,118,84,50,16 };
  50.         /* DO NOT ALTER! => 0x0123456789abcdeffedcba9876543210 <=       */
  51.  
  52. /* I/O declarations     */
  53. void ruderr(), put16(), vraiput(), initio();
  54. int IOedf, End, Once;
  55. BYTE Last[16];
  56.  
  57. int Ecb(), Cbc(), Cks();
  58. struct modes {
  59.         char *name;
  60.         int (*func)();
  61.         };
  62. struct modes ModsOp[MODS] = {   /* CAPS for CP/M - sorry!       */
  63.         { "ECB", Ecb },
  64.         { "CBC", Cbc },
  65.         { "CKS", Cks }  };
  66.  
  67. main(argc, argv)
  68. int argc;
  69. char **argv;
  70.         {
  71.         int (*xeqtr)();
  72.         int step, ende, edio, ok, i;
  73.         BYTE kv[16];
  74.  
  75.         argv++; argc--;
  76.         if(argc > 3 || argc < 2) ruderr();
  77.  
  78.         for(step=0; argc > 0; step++) {
  79.                 switch(step) {
  80.                 case 0: /* set en/de and/or default mode        */
  81.                         if(*argv[0] == '+' || *argv[0] == '-') {
  82.                                 ende = (*argv[0] == '+') ? EN : DE;
  83.                                 *argv[0]++ = NULL;
  84.                                 if(*argv[0] == NULL) {
  85.                                         xeqtr = Ecb;    /* default mode */
  86.                                         edio = ende;
  87.                                         argv++; argc--;
  88.                                         break;
  89.                                         }
  90.                                 }
  91.                         else ende = EN;
  92.  
  93.                         for(i=ok=0; i < MODS && !ok; i++) {
  94.                                 if(strcmp(argv[0], ModsOp[i].name) == 0) {
  95.                                         xeqtr = ModsOp[i].func;
  96.                                         ok = 1;
  97.                                         }
  98.                                 }
  99.                         if(!ok) {
  100.                                 fprintf(stderr, 
  101.                                 "Lucifer: unknown mode >%s<.\n", argv[0]);
  102.                                 ruderr();
  103.                                 }
  104.                         while(*argv[0]) *argv[0]++ = NULL;
  105.                         argv++; argc--;
  106.  
  107.                         /* set appropriate IO modes     */
  108.                         if(xeqtr == Cks) edio = CKS;
  109.                         else edio = ende;
  110.  
  111.                 /* falling through....  */
  112.                 case 1: /* get the key and IV, if needed and present    */
  113.                         if(strcmp(argv[0], "#") == 0) copy16(DFLTKY, kv);
  114.                         else getkey(argv[0], kv);
  115.                         argv++; argc--;
  116.                         
  117.                         /* if nothing left, but an IV needed, use the key    */
  118.                         if(argc == 0) {
  119.                                 if(xeqtr != Ecb) copy16(kv, IV);
  120.                                 break;
  121.                                 }
  122.                         else if(xeqtr == Ecb) {
  123.                                 fprintf(stderr, "Lucifer: ivec ignored.\n");
  124.                                 while(*argv[0]) *argv[0]++ = NULL;
  125.                                 argv++; argc--;
  126.                                 break;
  127.                                 }
  128.  
  129.                         else getkey(argv[0], IV);
  130.                         argv++; argc--;
  131.                         break;
  132.  
  133.                 default:
  134.                         fprintf(stderr, "Lucifer: Programming error!\n");
  135.                         exit(1);
  136.                         break;
  137.                         }       /* switch       */
  138.                 }       /* argument parsing     */
  139.  
  140.         initio(edio);
  141.         loadkey(kv, ende);
  142.         (*xeqtr)(ende); /* ta-da!  Take it away xeqtr!  */
  143.         exit(0);
  144.         }       /* end of main  */
  145.  
  146. void ruderr() {
  147.         fprintf(stderr,
  148.                 "Usage: lucifer (+|-)([ecb]|<cbc|cks>) key1 <ivec>\n");
  149.         exit(1);
  150.         }
  151.  
  152. Cbc(e_d)        /* Cipher Block Chaining                */
  153. int e_d;        /* Ciphertext errors are self-healing.  */
  154.         {
  155.         copy16(IV, Link);
  156.         while(get16(Block) != EOF) {
  157.                 if(e_d == DE) {
  158.                         copy16(Block, Temp);
  159.                         lucifer(Block);
  160.                         xor16(Block, Link);
  161.                         copy16(Temp, Link);
  162.                         }
  163.                 else {
  164.                         xor16(Block, Link);
  165.                         lucifer(Block);
  166.                         copy16(Block, Link);
  167.                         }
  168.                 put16(Block);
  169.                 }
  170.         return;
  171.         }
  172.  
  173. Cks(dummy)      /* CBC authentication checksum generator        */
  174. int dummy;      /* The banks use this for verifications.        */
  175.         {
  176.         int i, j, k;
  177.         long count = 0L;
  178.         copy16(IV, Link);
  179.         while(get16(Block) != EOF) {
  180.                 xor16(Block, Link);
  181.                 lucifer(Block);
  182.                 copy16(Block, Link);
  183.                 count++;
  184.                 }
  185.         fprintf(stdout, ": %0ld bytes\t: ", count<<4);
  186.         for(i=j=0; i < 4; i++) {
  187.                 for(k=0; k < 4; k++, j++)
  188.                         fprintf(stdout, "%02x", Link[j]&0377);
  189.                 putc(' ', stdout);
  190.                 }
  191.         fprintf(stdout, ":\n");
  192.         return;
  193.         }
  194.  
  195. Ecb(dummy)      /* Electronic Code Book : simple substitution   */
  196. int dummy;      /* Yawn.  For static data and random access.    */
  197.         {
  198.         while(get16(Block) != EOF) {
  199.                 lucifer(Block);
  200.                 put16(Block);
  201.                 }
  202.         return;
  203.         }
  204.  
  205. void copy16(from, to)
  206. register BYTE *from, *to;
  207.         {
  208.         register BYTE *ep;
  209.         ep = &to[16];
  210.         while(to < ep) *to++ = *from++;
  211.         return;
  212.         }
  213.  
  214. void xor16(to, with)
  215. register BYTE *to, *with;
  216.         {
  217.         register BYTE *ep;
  218.         ep = &to[16];
  219.         while(to < ep) *to++ ^= *with++;
  220.         return;
  221.         }
  222.  
  223. void put16(block)
  224. register BYTE *block;
  225.         {
  226.         if(IOedf == DE) copy16(block, Last);
  227.         else vraiput(block, &block[16]);
  228.         return;
  229.         }
  230.  
  231. get16(input)
  232. register BYTE *input;
  233.         {
  234.         register int i, j;
  235.         if(End == 1) return(EOF);       /* no more input        */
  236.  
  237.         for(i=0; i < 16 && ((j = getc(stdin)) != EOF); i++) *input++ = j;
  238.  
  239.         if(IOedf == DE) {       /* DECRYPTION   */
  240.                 /* complete block?  pending output?     */
  241.                 if(i == 16 && (Once > 0)) vraiput(Last, &Last[16]);
  242.                 else if(j == EOF) {
  243.                         End = 1;
  244.                         if(Once > 0) {
  245.                                 /* incomplete block means no nulls      */
  246.                                 if(i != 0) i = 0;
  247.                                 else {  
  248.                                         i = Last[15]&0377;
  249.                                         if(i > 16) i = 0;       /* huh? */
  250.                                         }
  251.                                 vraiput(Last, &Last[16-i]);
  252.                                 }
  253.                         return(EOF);
  254.                         }
  255.                 }
  256.         else if(j == EOF) {     /* ENCRYPTION   */
  257.                 End = 1;
  258.                 if(i == 0 && (IOedf == EN || (Once > 0))) {
  259.                         /* if no padding to do, print a kludge  */
  260.                         if(IOedf == EN && (Once > 0)) putc('0', stdout);
  261.                         return(EOF);
  262.                         }
  263.                 for(j=i; j < 15; j++) *input++ = NULL;
  264.                 *input = 16-i;
  265.                 }
  266.         Once = 1;
  267.         return(0);
  268.         }
  269.  
  270. void getkey(aptr, kptr)
  271. register char *aptr;
  272. register BYTE *kptr;
  273.         {
  274.         register BYTE *store;
  275.         register int i, first;
  276.         BYTE hold[16];
  277.         first = 1;
  278.         loadkey(DFLTKY, EN);
  279.         copy16(DFLTKY, hold);
  280.         while(*aptr || first) {
  281.                 store = kptr;
  282.                 for(i=0; i<16 && (*aptr != NULL); i++) {
  283.                         *store++ = toascii(*aptr);
  284.                         *aptr++ = NULL;
  285.                         }
  286.                 while(i++ < 16) *store++ = NULL;
  287.                 xor16(kptr, hold);
  288.                 lucifer(kptr);
  289.                 copy16(kptr, hold);
  290.                 first = 0;
  291.                 }
  292.         return;
  293.         }
  294.  
  295. void vraiput(cp, ep)
  296. register BYTE *cp, *ep;
  297.         {
  298.         while(cp < ep) putc((char)*cp++, stdout);
  299.         return;
  300.         }
  301.  
  302. void initio(edf)
  303. int edf;
  304.         {
  305.         IOedf = edf;
  306.         End = Once = 0;
  307.         return;
  308.         }
  309.  
  310. /* LUCIFER is a cryptographic algorithm developed by IBM in the early
  311.  *      seventies.  It was a predecessor of the DES, and is much simpler
  312.  *      than that algorithm.  In particular, it has only two substitution
  313.  *      boxes.  It does, however, use a 128 bit key and operates on
  314.  *      sixteen byte data blocks...
  315.  *
  316.  *      This implementation of LUCIFER was crafted by Graven Cyphers at the
  317.  *      University of Toronto, Canada, with programming assistance from
  318.  *      Richard Outerbridge.  It is based on the FORTRAN routines which
  319.  *      concluded Arthur Sorkin's article "LUCIFER: A Cryptographic Algorithm",
  320.  *      CRYPTOLOGIA, Volume 8, Number 1, January 1984, pp22-42.  The interested
  321.  *      reader should refer to that article rather than this program for more
  322.  *      details on LUCIFER.
  323.  *
  324.  *      These routines bear little resemblance to the actual LUCIFER algorithm,
  325.  *      which has been severely twisted in the interests of speed.  They do
  326.  *      perform the same transformations, and are believed to be UNIX portable.
  327.  *      The package was developed for use on UNIX-like systems lacking crypto
  328.  *      facilities.  They are not very fast, but the cipher is very strong.
  329.  *      The routines in this file are suitable for use as a subroutine library
  330.  *      after the fashion of crypt(3).  When linked together with applications
  331.  *      routines they can also provide a high-level cryptographic system.
  332.  *
  333.  *      -DENHANCE : modify LUCIFER by changing the key schedule and performing
  334.  *              an "autokeyed" encryption.  These may improve the algorithm.
  335.  */
  336.  
  337. #ifndef DE
  338. #define DE      1       /* for separate compilation     */
  339. #endif
  340.  
  341. static BYTE Dps[64] = { /* Diffusion Pattern schedule   */
  342.         4,16,32,2,1,8,64,128,   128,4,16,32,2,1,8,64,
  343.         64,128,4,16,32,2,1,8,   8,64,128,4,16,32,2,1,
  344.         1,8,64,128,4,16,32,2,   2,1,8,64,128,4,16,32,
  345.         32,2,1,8,64,128,4,16,   16,32,2,1,8,64,128,4    };
  346.  
  347. /* Precomputed S&P Boxes, Two Varieties */
  348. static BYTE TCB0[256] = {
  349.         87, 21,117, 54, 23, 55, 20, 84,116,118, 22, 53, 85,119, 52, 86,
  350.         223,157,253,190,159,191,156,220,252,254,158,189,221,255,188,222,
  351.         207,141,237,174,143,175,140,204,236,238,142,173,205,239,172,206,
  352.         211,145,241,178,147,179,144,208,240,242,146,177,209,243,176,210,
  353.         215,149,245,182,151,183,148,212,244,246,150,181,213,247,180,214,
  354.         95, 29,125, 62, 31, 63, 28, 92,124,126, 30, 61, 93,127, 60, 94,
  355.         219,153,249,186,155,187,152,216,248,250,154,185,217,251,184,218,
  356.         67,  1, 97, 34,  3, 35,  0, 64, 96, 98,  2, 33, 65, 99, 32, 66,
  357.         195,129,225,162,131,163,128,192,224,226,130,161,193,227,160,194,
  358.         199,133,229,166,135,167,132,196,228,230,134,165,197,231,164,198,
  359.         203,137,233,170,139,171,136,200,232,234,138,169,201,235,168,202,
  360.         75,  9,105, 42, 11, 43,  8, 72,104,106, 10, 41, 73,107, 40, 74,
  361.         91, 25,121, 58, 27, 59, 24, 88,120,122, 26, 57, 89,123, 56, 90,
  362.         71,  5,101, 38,  7, 39,  4, 68,100,102,  6, 37, 69,103, 36, 70,
  363.         79, 13,109, 46, 15, 47, 12, 76,108,110, 14, 45, 77,111, 44, 78,
  364.         83, 17,113, 50, 19, 51, 16, 80,112,114, 18, 49, 81,115, 48, 82 };
  365.  
  366. static BYTE TCB1[256] = {
  367.         87,223,207,211,215, 95,219, 67,195,199,203, 75, 91, 71, 79, 83,
  368.         21,157,141,145,149, 29,153,  1,129,133,137,  9, 25,  5, 13, 17,
  369.         117,253,237,241,245,125,249, 97,225,229,233,105,121,101,109,113,
  370.         54,190,174,178,182, 62,186, 34,162,166,170, 42, 58, 38, 46, 50,
  371.         23,159,143,147,151, 31,155,  3,131,135,139, 11, 27,  7, 15, 19,
  372.         55,191,175,179,183, 63,187, 35,163,167,171, 43, 59, 39, 47, 51,
  373.         20,156,140,144,148, 28,152,  0,128,132,136,  8, 24,  4, 12, 16,
  374.         84,220,204,208,212, 92,216, 64,192,196,200, 72, 88, 68, 76, 80,
  375.         116,252,236,240,244,124,248, 96,224,228,232,104,120,100,108,112,
  376.         118,254,238,242,246,126,250, 98,226,230,234,106,122,102,110,114,
  377.         22,158,142,146,150, 30,154,  2,130,134,138, 10, 26,  6, 14, 18,
  378.         53,189,173,177,181, 61,185, 33,161,165,169, 41, 57, 37, 45, 49,
  379.         85,221,205,209,213, 93,217, 65,193,197,201, 73, 89, 69, 77, 81,
  380.         119,255,239,243,247,127,251, 99,227,231,235,107,123,103,111,115,
  381.         52,188,172,176,180, 60,184, 32,160,164,168, 40, 56, 36, 44, 48,
  382.         86,222,206,210,214, 94,218, 66,194,198,202, 74, 90, 70, 78, 82 };
  383.  
  384. static BYTE Key[16], Pkey[128];
  385. static int P[8] = { 3,5,0,4,2,1,7,6 };
  386. static int Smask[16] = { 128,64,32,16,8,4,2,1 };
  387.  
  388. void lucifer(bytes)
  389. BYTE *bytes;    /* points to a 16-byte array    */
  390.         {
  391.         register BYTE *cp, *sp, *dp;
  392.         register int val, *sbs, tcb, j, i;
  393.         BYTE *h0, *h1, *kc, *ks;
  394.  
  395.         h0 = bytes;     /* the "lower" half     */
  396.         h1 = &bytes[8]; /* the "upper" half     */
  397.         kc = Pkey;
  398.         ks = Key;
  399.  
  400.         for(i=0; i<16; i++) {
  401.                 tcb = *ks++;
  402.                 sbs = Smask;
  403.                 dp = Dps;
  404.                 sp = &h0[8];
  405. #ifdef ENHANCE
  406.                 for(j=0, cp=h1; j<8; j++) tcb ^= *cp++;
  407. #endif
  408.                 for(j=0; j<8; j++) {
  409.                         if(tcb&*sbs++) val = TCB1[h1[j]&0377];
  410.                         else val = TCB0[h1[j]&0377];
  411.                         val ^= *kc++;
  412.                         for(cp=h0; cp<sp;) *cp++ ^= (val&*dp++);
  413.                         }
  414.  
  415.                 /* swap (virtual) halves        */
  416.                 cp = h0;
  417.                 h0 = h1;
  418.                 h1 = cp;
  419.                 }
  420.  
  421.         /* REALLY swap halves   */
  422.         dp = bytes;
  423.         cp = &bytes[8];
  424.         for(sp=cp; dp<sp; dp++, cp++) {
  425.                 val = *dp;
  426.                 *dp = *cp;
  427.                 *cp = val;
  428.                 }
  429.         return;
  430.         } 
  431.  
  432. void loadkey(keystr, edf)       /* precomputes the key schedules        */
  433. BYTE *keystr;
  434. register int edf;
  435.         {
  436.         register BYTE *ep, *cp, *pp;
  437.         register int kc, i, j;
  438.         BYTE kk[16], pk[16];
  439.         cp = kk;
  440.         pp = pk;
  441.         ep = &kk[16];
  442.         while(cp < ep) {
  443.                 *cp++ = *keystr;
  444.                 for(*pp=i=0; i<8; i++)
  445.                         if(*keystr&Smask[i]) *pp |= Smask[P[i]];
  446.                 keystr++;
  447.                 pp++;
  448.                 }
  449.         cp = Key;
  450.         pp = Pkey;
  451.         kc = (edf == DE) ? 8 : 0;
  452.         for(i=0; i<16; i++) {
  453.                 if(edf == DE) kc = (++kc)&017;
  454. #ifdef ENHANCE
  455.                 *cp++ = kk[( (kc == 0) ? 15 : (kc - 1) )];
  456. #else
  457.                 *cp++ = kk[kc];
  458. #endif 
  459.                 for(j=0; j<8; j++) {
  460.                         *pp++ = pk[kc];
  461.                         if(j<7 || (edf == DE)) kc = (++kc)&017;
  462.                         }
  463.                 }
  464.         return;
  465.         }
  466.  
  467. /* lucifer cks # < /dev/null 
  468.  *      : 16 bytes      : 32186510 6acf6094 87953eba 196f5a75 :
  469.  *      (-DENHANCE)     : 378cfd5b bd54a07b 28513809 624e6071 :
  470.  *                      (rwo/8412.03.18:10/V5.0)                */
  471. /************************ lucifer *******************************/
  472.